feat: lumped loads, phased feeders, and four reworked antenna models#65
Merged
Conversation
…ions The driven element and reflector were ~2.8x too wide (~1.04 wavelength instead of ~0.37), which detuned the antenna and produced SWR >99 across the entire band. Two compounding errors in moxonDimensions(): - The polynomial coefficients did not match the standard Cebik/MoxGen Moxon equations. - The full element width A was treated as a half-width and then doubled. Replaced the formulas with L.B. Cebik's (W4RNL) MoxGen regression equations and corrected the full-width vs. half-width handling. The 14.15 MHz / 2 mm design now comes out to 7.73 m x 2.81 m, matching MoxGen. Closes #63
The End-Fed Half-Wave geometry fixed the horizontal span at the half-wave length and set the far-end height independently, so the actual conductor was the hypotenuse — longer than a half-wave whenever the ends were at different heights. With the default 40m design (feed 10 m, far end 3 m) the wire came out 21.66 m instead of 20.49 m (~5.7% long), pushing resonance below the swept band and leaving SWR ~3.9 at the design frequency. The horizontal run is now derived from the height drop so the conductor is always a true half-wave; changing the far-end height tilts the sloper instead of stretching the wire. A clamp keeps the geometry valid if the requested height drop exceeds the wire length. Verified with nec2c (average ground, 49:1 transform): SWR at the 7.1 MHz design point drops from 3.88 to 1.49, with resonance landing near the design frequency.
The fan dipole only matched on its lowest band; 20m and 10m showed very high SWR. Three compounding problems: 1. Feed topology: every element's left and right halves all terminated at one common node, with the source on the longest element's segment. Only that dipole straddled the source across its center and was driven differentially; the other elements had both halves tied to the same node, so they were never excited as dipoles and hung off the feed as quasi-parasitic stubs (high, reactive impedance -> very high SWR). 2. Fan spread stretched each element: the horizontal span was fixed at the half-length while the ends dropped vertically, so the conductor was longer than its resonant length (worse on higher bands). 3. End-effect shortening put the coupled elements above their bands. Now all left halves join a left terminal and all right halves a right terminal, bridged by a short driven feed segment, so every dipole is fed across its center simultaneously. Each arm is held at a fixed length and the fan spread only tilts it. Element length compensates for the upward resonance shift caused by fan mutual coupling. Verified with nec2c (average ground, default 40/20/10m design): in-band SWR at band centers improves from ~1.8/14/27 to ~2.7/2.3/1.9 for 40m/20m/10m. Fan dipoles still benefit from per-element trimming in practice, but all bands are now usable out of the box.
The AntennaTemplate interface only allowed a single excitation and no lumped loads, so antennas that need a tuning capacitor (magnetic loop), a phased feeder (log-periodic), or a transmission-line feeder (G5RV) could not be modelled correctly in the simulator. Extend the interface: - generateExcitation may now return Excitation | Excitation[] - add optional generateLoads() and generateTransmissionLines() The downstream advanced engine path (simulateAdvanced) already supports excitation arrays, loads and transmission lines end to end, so the simulator now dispatches through it instead of the single-excitation V1 path. antennaStore normalises the excitation to an array and invokes the optional load/TL generators; the editor's Load Template carries them over too. Existing single-excitation templates are untouched (the union keeps a bare Excitation valid). Verified against the backend (nec2c) that a dipole returns identical results through the new path: min SWR 1.424 @ 14.473 MHz, Z 71.0-2.6j, gain 7.2.
The Small Magnetic Loop never resonated: it had no tuning capacitor (so the electrically tiny loop was a pure inductive reactance) and was fed directly (a resonant small loop is well under 1 ohm, so even resonant it would be a near-total mismatch). SWR pegged near infinity across the band. Model it the way a real small transmitting loop works, using the new template load capability: - a closed main loop carrying a series tuning capacitor at the top, with C computed from the loop inductance (mu0*a*(ln(8a/b)-2)) and an empirical correction calibrated against nec2c so it resonates on frequency; - a small fed Faraday coupling loop near the bottom that transforms the loop's sub-ohm radiation resistance up to ~50 ohms. Each arc segment is its own unique-tag wire so the feed and capacitor can address a specific point (the backend validates excitation segments per wire). Two new controls mirror real loop tuning: Coupling Loop Size sets the feed resistance, Capacitor Tuning peaks resonance. The default frequency sweep is tightened because the loop is only a few kHz wide. Verified end to end against the backend (nec2c): SWR ~500 -> ~1.4 at resonance for the default design, and the recipe generalises across loop sizes and bands. Also fixed the feedpoint marker, which used Three.js coordinates instead of the NEC coordinates the viewport expects.
The 450-ohm matching section was modelled as a single vertical wire, which radiates and presents a common-mode impedance unlike a balanced line, so the default G5RV showed ~99:1 SWR. Model it instead as a NEC transmission line between the dipole center and a short coax stub, with the line length scaled by the 0.91 velocity factor of 450-ohm window line (NEC's TL is ideal, VF=1). Verified with nec2c: ~1.9:1 on 20m (the G5RV's design band), with realistic tuner-needed behaviour on the other bands.
Transmission lines are non-radiating (ideal 2-port) elements, so they were not drawn at all — leaving the feedpoint of a TL-fed antenna (e.g. the G5RV) floating disconnected from the antenna. Add a reusable NonRadiatingLines component plus a resolver that turns TL port references into 3D segments, and render them dashed in both the Simulator (SceneRoot) and Wire Editor (EditorScene) viewports.
The LPDA fed only the front element and left the rest as floating parasitics, so it produced no real log-periodic behaviour. Model the proper phase-line feeder using the new template transmission-line capability: - a Carrel-designed feeder characteristic impedance derived from tau, sigma, the element impedance and the 50-ohm target; - crossed (transposed) transmission lines between adjacent element centers, giving the 180-degree alternation (negative NEC Z0); - a shorted rear termination stub behind the longest element; - an element range extended past both band edges so the active region never runs off the front element. The backend rejected negative transmission-line impedance, but that is NEC's convention for a crossed/transposed line, so the constraint is relaxed to allow it (magnitude still bounded). Verified end to end against the backend (nec2c): ~11 dBi forward gain and SWR mostly under 2 across the full 14-30 MHz design range.
…efs valid Two issues made the G5RV/LPDA feeder dashed line render off-vertical: 1. The Wire Editor re-segments wires when the design frequency changes, scaling excitation segments but not transmission-line or lumped-load segment references. A loaded G5RV's feeder then pointed at segment 21 of a re-segmented 9-segment wire, so the viewport extrapolated past the wire end (~52deg) and the line was also invalid for simulation. setDesignFrequency now scales TL and load segments the same way, and the viewport defensively clamps a stale reference onto the wire. 2. The G5RV fed the transmission line from the last segment of a dipole arm, whose center sits half a segment short of the true dipole center (~5deg with coarse segmentation). Model the dipole as a single wire fed at its center segment instead (autoSegment returns odd counts, so the center segment is the exact midpoint). Verified with nec2c that this is electrically identical to the two-arm version (1.85 vs 1.86 on 20m). The feeder now renders perfectly vertical in both views.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends the antenna template system to model antennas that need lumped loads, transmission-line feeders, or phased feeds — then reworks four templates that were structurally broken without those capabilities. Every antenna is
validated end-to-end against nec2c. Releases v1.2.0.
Foundation
Antenna fixes
(sets feed resistance) and Capacitor Tuning (peaks resonance). nec2c: SWR ~500 → ~1.4.
termination stub, and an element range extended past both band edges. nec2c: ~11 dBi forward gain, SWR mostly <2 across 14–30 MHz.
Viewport
Backend
Release
Testing
▎ Note: this PR touches the backend (antenna.py), so it exercises both services — after merge, the backend must include this change for the LPDA's transposed feeder.